package client;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.*;

import msgs.*;
/**
 * Parses the incoming PM Messages
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 * @author Ryan Kortmann
 */
public class PMParser extends Thread implements TTConstants {
	private SimpleMsg smsg;
	private static boolean go;
	
	public PMParser() {
		go = true;
	}
	
	public void run() {
		while (go) {
			// if we have a message, parse it
			if (!(PMListener.inQ.isEmpty())) {
				smsg = PMListener.inQ.remove(0);
				
				// check to see if this is a file message request
				if (smsg instanceof FileMsg) {
					// this code is UGLY.
					(new Thread() {
						public void run() {
							if (((FileMsg)smsg).isRequest()) {
								// IF we this is just a request and IF it's not been ok'ed , complain
								if (!((FileMsg)smsg).isRequestOK()) {
									JOptionPane.showMessageDialog(null, ((FileMsg)smsg).getTo() + " denied your file request", "File request denied", JOptionPane.INFORMATION_MESSAGE);
									return;
								}
								else {
									// otherwise, it wasn't NOT ok'ed, but maybe we need to answer it
									// determine if we're needing to answer
									if (!((FileMsg)smsg).isIAnsweredTheDamnQuestionAlready()) {
										// ok, we need to answer
										int response = JOptionPane.showConfirmDialog(null, ((FileMsg)smsg).getFrom() + " wants to send you a file. Accept?", "File transfer request", JOptionPane.YES_NO_OPTION);
										if (response == JOptionPane.YES_OPTION) {
											((FileMsg)smsg).setRequestOK(true);
										}
										else {
											((FileMsg)smsg).setRequestOK(false);
										}
										((FileMsg)smsg).setIAnsweredTheDamnQuestionAlready(true);
										PMSender.outQ.add(smsg);
										return;
									}
									
									// we didnt have to answer it. then we must need to send a file
									File f = new File(((FileMsg)smsg).getFname());
									byte[] inbuf = new byte[(int)f.length()];
									try {
										// this just reads the file into an array of bytes
										// this is limited to the java heap size, which is rather low in many cases.
										// in my testing we were limited to files of about 100mb
										// setting a larger heap size on the command line alleviates this
										InputStream is = new FileInputStream(f);
										int offset = 0;
								        int numRead = 0;
								        while (offset < inbuf.length
								               && (numRead=is.read(inbuf, offset, inbuf.length-offset)) >= 0) {
								            offset += numRead;
								        }

									}
									catch (Exception e) {e.printStackTrace();}
									((FileMsg)smsg).setFile(inbuf);
									((FileMsg)smsg).setRequest(false);
									// send it over. this could cause problems on a slow connection, you've been warned
									PMSender.outQ.add(smsg);
								}
								
							}
							else {
								// ok we need to receive a file
								byte[] inbuf = ((FileMsg)smsg).getFile();
								// find out where they want to save it
								JFileChooser jfc = new JFileChooser();
								int result = jfc.showSaveDialog(null);
								if (result == JFileChooser.APPROVE_OPTION) {
									File f = jfc.getSelectedFile();
									try {
										// save the file
										FileOutputStream fos = new FileOutputStream(f);
										fos.write(inbuf);
										fos.flush();
									}
									catch (Exception e) { e.printStackTrace(); }
								}
 							}
						}
					}).start();
				}
				
				// ok, not a file request transfer thing, they must want to talk
				if (TTClient.pmChats.containsKey(smsg.getFrom())) {
					// they already have a chat going, raise the window and update
					TTClient.pmChats.get(smsg.getFrom()).setVisible(true);
					TTClient.pmChats.get(smsg.getFrom()).updateWindow(smsg.getMsg());
					TTClient.playMsgIn();;
				}
				else {
					// new request. someone loves us!
					TTClient.pmChats.put(smsg.getFrom(), new PMChat(new PMMsg(TTClient.ip, TTClient.name, null, TTClient.key, smsg.getFrom())));
					TTClient.pmChats.get(smsg.getFrom()).updateWindow(smsg.getMsg());
					TTClient.pmChats.get(smsg.getFrom()).setFromIP(smsg.getFromIp());
					TTClient.playMsgIn();
				}
			}
			else {
				// nothing to do, sleep so we dont kill processor usage
				try { Thread.sleep(100); }
				catch (Exception e) {} 
			}
		}
	}
	
	/**
	 * Cleanly shuts down this parser
	 */
	 public static void killPMParser() {
			while (go) {
				if (PMListener.inQ.isEmpty()) go = false;
				else try {
					Thread.sleep(10);
				} 
				catch (Exception e) {}
			}
		}
}
